/*
 *    Copyright (c) 2014 Xiang Xu <xuxiang@mail.bnu.edu.cn>
 *
 *    Permission is hereby granted, free of charge, to any person
 *    obtaining a copy of this software and associated documentation
 *    files (the "Software"), to deal in the Software without
 *    restriction, including without limitation the rights to use,
 *    copy, modify, merge, publish, distribute, sublicense, and/or sell
 *    copies of the Software, and to permit persons to whom the
 *    Software is furnished to do so, subject to the following
 *    conditions:
 *
 *    The above copyright notice and this permission notice shall be
 *    included in all copies or substantial portions of the Software.
 *
 *    THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
 *    EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
 *    OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
 *    NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
 *    HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
 *    WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
 *    FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
 *    OTHER DEALINGS IN THE SOFTWARE.
 */


#ifndef PCLWRAPER_H
#define PCLWRAPER_H

#include "status.h"
#include "pcl/io/pcd_io.h"
#include "pcl/io/ply_io.h"

class PclWraper
{

public:
    PclWraper();
    virtual ~PclWraper();

    static Status XYZ2PCD(const std::string& file_path, pcl::PointCloud<pcl::PointXYZ>::Ptr cloud);
    static Status XYZL2PCD(const std::string& file_path, pcl::PointCloud<pcl::PointXYZ>::Ptr cloud);
    static Status PLY2PCD(const std::string& file_path, pcl::PointCloud<pcl::PointXYZ>::Ptr cloud);

    static Status LoadPCD(const std::string& file_path, pcl::PointCloud<pcl::PointXYZ>::Ptr cloud);
    static Status SavePCD(const std::string& file_path, pcl::PointCloud<pcl::PointXYZ>::Ptr cloud, bool binary = false);

    static Status GridSample(pcl::PointCloud<pcl::PointXYZ>::Ptr input, pcl::PointCloud<pcl::PointXYZ>::Ptr output,
                             double size_x, double size_y, double size_z);

    static Status RadiusOutlier(pcl::PointCloud<pcl::PointXYZ>::Ptr input, pcl::PointCloud<pcl::PointXYZ>::Ptr output,
                                double radius, int min_neighbors);

    static Status StatiscalOutlier(
        pcl::PointCloud<pcl::PointXYZ>::Ptr input, pcl::PointCloud<pcl::PointXYZ>::Ptr output,
        int num_neighbors,	//  The number of neighbors to analyze for each point
        double stddevmul, // all points who have a distance larger than @stddevmul@ standard deviation of the mean distance
        // to the query point will be marked as outliers and removed.
        bool inliers
    );

    static Status PassThroughFilter(
        pcl::PointCloud<pcl::PointXYZ>::Ptr input,		// input cloud
        pcl::PointCloud<pcl::PointXYZ>::Ptr output,
        const std::string& axe,			//  filter field name is which coordinate? can be: "x", "y" or "z"
        double minLimits,				// min range
        double maxLimits,				// max range
        bool inside						// inside or outside a given user range.
    );

    static Status ExtractPlane(pcl::PointCloud<pcl::PointXYZ>::Ptr input,		// input cloud
                               pcl::PointCloud<pcl::PointXYZ>::Ptr output,
                               double threshold,
                               Eigen::VectorXf& plane_coeff
                              );

    static Status ComputeNormal(pcl::PointCloud<pcl::PointXYZ>::Ptr input,
                                pcl::PointCloud<pcl::Normal>::Ptr cloud_normals);
};

#endif // PCLWRAPER_H
